/**
 * 函数节流方法
 * @param Function fn 延时调用函数
 * @param Number delay 延迟多长时间
 * @param Number atleast 至少多长时间触发一次
 * @return Function 延迟执行的方法
 *
 * @Example: const ThrottleFn = new Throttle(fn, delay, atleast);ThrottleFn.start()
 */
export class Throttle {
  constructor(fn, delay, atleast) {
    this.fn = fn
    this.delay = delay
    this.atleast = atleast
    this.init()
  }

  init() {
    this.previous = null
    this.timer = null
  }

  start(payload) {
    let now = +new Date()

    if (!this.previous) {
      this.previous = now
    }

    // 如果上一次与本次的时间差大于最小触发值，就走最小触发值的逻辑
    // 否则走 timeout 的逻辑
    if (now - this.previous > this.atleast) {
      this.atleastCond(payload)
    } else {
      this.timeoutCond(payload)
    }
  }

  atleastCond(payload) {
    this.fn(payload)
    this.previous = +new Date()
  }

  timeoutCond(payload) {
    clearTimeout(this.timer)
    this.timer = setTimeout(() => {
      this.fn(payload)
      this.previous = null
    }, this.delay)
  }
}
